package com.scheduling.schedule.mapper;

import com.scheduling.schedule.entity.MachineLoad;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 机器负荷数据访问层
 *
 * @author 开发团队
 */
@Mapper
public interface MachineLoadMapper {

    /**
     * 插入机器负荷记录
     */
    @Insert("INSERT INTO machine_load (load_id, machine_id, task_id, start_time, end_time, status, create_time) " +
            "VALUES (#{loadId}, #{machineId}, #{taskId}, #{startTime}, #{endTime}, #{status}, #{createTime})")
    int insert(MachineLoad machineLoad);

    /**
     * 批量插入机器负荷记录
     */
    @Insert("<script>" +
            "INSERT INTO machine_load (load_id, machine_id, task_id, start_time, end_time, status, create_time) " +
            "VALUES " +
            "<foreach collection='list' item='item' separator=','>" +
            "(#{item.loadId}, #{item.machineId}, #{item.taskId}, #{item.startTime}, #{item.endTime}, #{item.status}, " +
            "#{item.createTime})" +
            "</foreach>" +
            "</script>")
    int batchInsert(@Param("list") List<MachineLoad> machineLoads);

    /**
     * 根据负荷ID查询
     */
    @Select("SELECT * FROM machine_load WHERE load_id = #{loadId}")
    MachineLoad selectByLoadId(@Param("loadId") String loadId);

    /**
     * 根据任务ID查询
     */
    @Select("SELECT * FROM machine_load WHERE task_id = #{taskId}")
    MachineLoad selectByTaskId(@Param("taskId") String taskId);

    /**
     * 根据机器ID查询所有负荷记录
     */
    @Select("SELECT * FROM machine_load WHERE machine_id = #{machineId} ORDER BY start_time ASC")
    List<MachineLoad> selectByMachineId(@Param("machineId") String machineId);

    /**
     * 获取机器的最新负荷记录
     */
    @Select("SELECT * FROM machine_load WHERE machine_id = #{machineId} " +
            "ORDER BY end_time DESC LIMIT 1")
    MachineLoad getLatestLoadByMachineId(@Param("machineId") String machineId);

    /**
     * 查询机器在指定时间段的负荷记录
     */
    @Select("SELECT * FROM machine_load WHERE machine_id = #{machineId} " +
            "AND ((start_time <= #{endTime} AND end_time >= #{startTime})) " +
            "ORDER BY start_time ASC")
    List<MachineLoad> selectByMachineAndPeriod(@Param("machineId") String machineId,
                                               @Param("startTime") LocalDateTime startTime,
                                               @Param("endTime") LocalDateTime endTime);

    /**
     * 查询所有机器负荷记录
     */
    @Select("SELECT * FROM machine_load ORDER BY machine_id, start_time ASC")
    List<MachineLoad> selectAll();

    /**
     * 查询指定状态的机器负荷记录
     */
    @Select("SELECT * FROM machine_load WHERE status = #{status} ORDER BY start_time ASC")
    List<MachineLoad> selectByStatus(@Param("status") String status);

    /**
     * 查询指定时间段内的所有负荷记录
     */
    @Select("SELECT * FROM machine_load WHERE start_time >= #{startTime} AND end_time <= #{endTime} " +
            "ORDER BY machine_id, start_time ASC")
    List<MachineLoad> selectByTimePeriod(@Param("startTime") LocalDateTime startTime,
                                         @Param("endTime") LocalDateTime endTime);

    /**
     * 更新机器负荷状态
     */
    @Update("UPDATE machine_load SET status = #{status} WHERE load_id = #{loadId}")
    int updateStatus(@Param("loadId") String loadId, @Param("status") String status);

    /**
     * 更新机器负荷时间
     */
    @Update("UPDATE machine_load SET start_time = #{startTime}, end_time = #{endTime} " +
            "WHERE load_id = #{loadId}")
    int updateTime(@Param("loadId") String loadId,
                   @Param("startTime") LocalDateTime startTime,
                   @Param("endTime") LocalDateTime endTime);

    /**
     * 根据任务ID删除负荷记录
     */
    @Delete("DELETE FROM machine_load WHERE task_id = #{taskId}")
    int deleteByTaskId(@Param("taskId") String taskId);

    /**
     * 根据任务ID批量删除负荷记录
     */
    @Delete("<script>" +
            "DELETE FROM machine_load WHERE task_id IN " +
            "<foreach collection='taskIds' item='taskId' open='(' separator=',' close=')'>" +
            "#{taskId}" +
            "</foreach>" +
            "</script>")
    int deleteBatchByTaskIds(@Param("taskIds") List<String> taskIds);

    /**
     * 根据负荷ID删除记录
     */
    @Delete("DELETE FROM machine_load WHERE load_id = #{loadId}")
    int deleteByLoadId(@Param("loadId") String loadId);

    /**
     * 删除指定机器的所有负荷记录
     */
    @Delete("DELETE FROM machine_load WHERE machine_id = #{machineId}")
    int deleteByMachineId(@Param("machineId") String machineId);

    /**
     * 删除指定时间之前的历史负荷记录
     */
    @Delete("DELETE FROM machine_load WHERE end_time < #{endTime}")
    int deleteHistoryBefore(@Param("endTime") LocalDateTime endTime);

    /**
     * 统计机器在指定时间段的工作时长
     */
    @Select("SELECT COALESCE(SUM(TIMESTAMPDIFF(MINUTE, " +
            "GREATEST(start_time, #{startTime}), " +
            "LEAST(end_time, #{endTime}))), 0) as work_minutes " +
            "FROM machine_load WHERE machine_id = #{machineId} " +
            "AND start_time < #{endTime} AND end_time > #{startTime}")
    Long getWorkMinutesInPeriod(@Param("machineId") String machineId,
                                @Param("startTime") LocalDateTime startTime,
                                @Param("endTime") LocalDateTime endTime);

    /**
     * 获取机器负荷详情（关联查询）
     */
    @Select("SELECT ml.*, m.machine_name, mt.type_name, pt.operation_id " +
            "FROM machine_load ml " +
            "JOIN machine m ON ml.machine_id = m.machine_id " +
            "JOIN machine_type mt ON m.machine_type_id = mt.machine_type_id " +
            "LEFT JOIN production_task pt ON ml.task_id = pt.task_id " +
            "WHERE ml.machine_id = #{machineId} " +
            "ORDER BY ml.start_time ASC")
    List<MachineLoad> selectDetailsByMachineId(@Param("machineId") String machineId);

    /**
     * 检查时间冲突
     */
    @Select("SELECT COUNT(*) FROM machine_load WHERE machine_id = #{machineId} " +
            "AND ((start_time <= #{endTime} AND end_time >= #{startTime})) " +
            "AND status IN ('计划', '执行中')")
    int countTimeConflicts(@Param("machineId") String machineId,
                           @Param("startTime") LocalDateTime startTime,
                           @Param("endTime") LocalDateTime endTime);
} 